package ru.neoflex.jedit.plugin.utils;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class XmlUtils {
    private static DocumentBuilderFactory documentBuilderFactory;

    private static DocumentBuilderFactory getDocumentBuilderFactory() throws ParserConfigurationException {
        if (documentBuilderFactory == null) {
            documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setValidating(false);
            documentBuilderFactory.setFeature("http://xml.org/sax/features/namespaces", false);
            documentBuilderFactory.setFeature("http://xml.org/sax/features/validation", false);
            documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
            documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        }
        return documentBuilderFactory;
    }

    public static Document parseXml(File xmlFile) throws ParserConfigurationException, IOException, SAXException {
        Assert.notNull(xmlFile);

        DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder();
        return documentBuilder.parse(xmlFile);
    }

    public static List<Map<String, String>> getTagsByName(Document doc, String name) {
        List<Map<String, String>> result = new ArrayList<Map<String, String>>();

        DocumentTraversal traversal = (DocumentTraversal) doc;
        NodeIterator it = traversal.createNodeIterator(doc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);
        Node node = it.nextNode();
        while (node != null) {
            String nodeName = node.getNodeName();
            if (nodeName.equals(name)) {
                Map<String, String> item = new HashMap<String, String>();

                for (int i = 0; i < node.getAttributes().getLength(); i++) {
                    String key = node.getAttributes().item(i).getNodeName();
                    String value = node.getAttributes().item(i).getNodeValue();
                    item.put(key, value);
                }

                result.add(item);
            }
            node = it.nextNode();
        }

        return result;
    }
}
